/*
 * Spring 2012 TCSS360 Deliverable 3
 * Otis Alexander
 * Matthew Selfors
 */

package gui;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Point;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.io.File;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.List;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.JTextField;
import javax.swing.ListSelectionModel;
import javax.swing.SwingConstants;
import javax.swing.table.TableModel;

import model.Auction;
import model.CalendarModel;
import model.User;
import model.UserAccess;
import storage.ProgramStateHandler;

@SuppressWarnings("serial")
public class CalendarGUI extends JPanel {

	private static final String[] MONTH = {"January",
			"February", "March", "April", "May", "June",
			"July", "August", "September", "October",
			"November", "December"};

	private JFrame frame;

	private CalendarModel calendar_model;

	private Calendar calendar_object;

	private Calendar temp_calendar;

	private JScrollPane scroll_pane;

	private JTable table;

	private MyTableModel tableModel;

	private JTextField month;

	private int current_month;

	private JPanel north_panel;

	private String npo;

	private Auction a;

	private User my_user;

	private UserAccess my_ua;

	private ProgramStateHandler my_ps;

	public CalendarGUI(
			final CalendarModel the_calendar_model,
			final User user, final ProgramStateHandler ps,
			final UserAccess ua) {
		super();
		frame = new JFrame();
		frame.setPreferredSize(new Dimension(800, 600));
		frame.setResizable(false);
		frame.addWindowListener(new java.awt.event.WindowAdapter() {
			public void windowClosing(
					java.awt.event.WindowEvent e) {
				ps.write(new File("file.xml"),
						the_calendar_model, ua);
				System.exit(0);
			}
		});
		frame.add(this);
		calendar_model = the_calendar_model;
		calendar_object = calendar_model.calendar;
		temp_calendar = calendar_object;
		setLayout(new BorderLayout());
		north_panel = new JPanel(new BorderLayout());
		add(north_panel, BorderLayout.NORTH);

		setUpTable();
		add(scroll_pane, BorderLayout.CENTER);

		setUpMonth();
		north_panel.add(month, BorderLayout.CENTER);

		monthButtons();

		tableModel =
				new MyTableModel(temp_calendar,
						calendar_model);
		tableModel.fillDays(current_month);

		frame.setVisible(true);
		frame.pack();
		table.setModel(tableModel);
		table.repaint();
		my_user = user;
		my_ua = ua;
		my_ps = ps;
		frame.setLocationRelativeTo(null);
	}

	private void setUpTable() {
		table = new JTable();
		table.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);

		table.addMouseListener(new MouseAdapter() {
			public void mouseClicked(MouseEvent e) {
				if (e.getClickCount() == 1) {
					int mouse_x = e.getX();
					int mouse_y = e.getY();

					JTable target = (JTable) e.getSource();
					int row =
							target.rowAtPoint(new Point(
									mouse_x, mouse_y));
					int column =
							target.columnAtPoint(new Point(
									mouse_x, mouse_y));
					TableModel tm = target.getModel();
					Class<? extends TableModel> c =
							target.getModel().getClass();
					if (tm != null
							&& c == MyTableModel.class) {
						if (row != -1 && column != -1) {
							JPanel jp =
									(JPanel) target
											.getModel()
											.getValueAt(
													row,
													column);
							Component[] components =
									jp.getComponents();
							if (components.length > 1) {
								AuctionGUI a_gui =
										new AuctionGUI(a,
												my_user);
								a_gui.start(my_ps,
										calendar_model,
										my_ua);
							}
						}
					}
				}
			}
		});

		table.addMouseMotionListener(new MouseAdapter() {

			public void mouseMoved(MouseEvent e) {
				int mouse_x = e.getX();
				int mouse_y = e.getY();
				int y;

				JTable target = (JTable) e.getSource();
				int row =
						target.rowAtPoint(new Point(
								mouse_x, mouse_y));
				int column =
						target.columnAtPoint(new Point(
								mouse_x, mouse_y));
				TableModel tm = target.getModel();
				Class<? extends TableModel> c =
						target.getModel().getClass();
				if (tm != null && c == MyTableModel.class) {
					if (row != -1 && column != -1) {
						JPanel jp =
								(JPanel) target.getModel()
										.getValueAt(row,
												column);
						Component[] components =
								jp.getComponents();
						if (components.length > 1) {
							JLabel jl;
							if (mouse_y <= 80) {
								y = mouse_y;
							} else {
								y = mouse_y - (row * 80);
							}

							if (y >= 15 && y <= 30) {
								jl = (JLabel) components[1];
								npo = jl.getText();
								jl = (JLabel) components[0];
								a =
										getAuction(jl
												.getText(),
												npo);
								jp.setToolTipText(a
										.getName()
										+ " "
										+ "Start Time: "
										+ a.getStartTime()
										+ " "
										+ "End Time: "
										+ a.getEndTime());
								repaint();
							} else if (y >= 31
									&& components.length > 2) {
								jl = (JLabel) components[2];
								npo = jl.getText();
								jl = (JLabel) components[0];
								a =
										getAuction(jl
												.getText(),
												npo);
								jp.setToolTipText(a
										.getName()
										+ " "
										+ "Start Time: "
										+ a.getStartTime()
										+ " "
										+ "End Time: "
										+ a.getEndTime());
								repaint();
							}
						}
					}
				}
			}
		});

		table.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
		table.setCellSelectionEnabled(false);
		table.setRowHeight(80);
		scroll_pane = new JScrollPane(table);
		table.setAutoResizeMode(JTable.AUTO_RESIZE_ALL_COLUMNS);
		table.getTableHeader().setReorderingAllowed(false);
		table.setDefaultRenderer(JPanel.class,
				new CellRenderer());
	}

	private void setUpMonth() {
		Font font = new Font("month", 0, 48);
		month =
				new JTextField(
						MONTH[calendar_model.calendar
								.get(Calendar.MONTH)]);
		current_month =
				calendar_model.calendar.get(Calendar.MONTH);
		month.setFont(font);
		month.setHorizontalAlignment(SwingConstants.CENTER);
		month.setBackground(Color.WHITE);
		month.setEditable(false);
	}

	private void monthButtons() {
		Font font = new Font("arrows", 0, 48);
		JButton prev_month = new JButton("<");
		JButton next_month = new JButton(">");
		prev_month.setFont(font);
		next_month.setFont(font);

		MonthListener month_listener = new MonthListener();

		prev_month.addActionListener(month_listener);
		next_month.addActionListener(month_listener);

		north_panel.add(prev_month, BorderLayout.WEST);
		north_panel.add(next_month, BorderLayout.EAST);
	}

	private class MonthListener implements ActionListener {

		@Override
		public void actionPerformed(
				final ActionEvent the_event) {
			if (the_event.getActionCommand().equals("<")) {
				if (current_month == 0) {
					month.setText(MONTH[MONTH.length - 1]);
					current_month = MONTH.length - 1;
					tableModel.fillDays(current_month);
					table.setModel(tableModel);
					table.repaint();
				} else {
					month.setText(MONTH[current_month - 1]);
					current_month--;
					tableModel.fillDays(current_month);
					table.setModel(tableModel);
					table.repaint();
				}
			} else {
				if (current_month == MONTH.length - 1) {
					month.setText(MONTH[0]);
					current_month = 0;
					tableModel.fillDays(current_month);
					table.setModel(tableModel);
					table.repaint();
				} else {
					month.setText(MONTH[current_month + 1]);
					current_month++;
					tableModel.fillDays(current_month);
					table.setModel(tableModel);
					table.repaint();
				}
			}
		}
	}

	private Auction getAuction(String day, String npo) {
		Date d =
				convertDate(MONTH[current_month] + " "
						+ day + ", 2012");
		List<Auction> auction_list =
				calendar_model.getAuctions(d);
		if (auction_list != null) {
			for (int i = 0; i < auction_list.size(); i++) {
				if (auction_list.get(i).getNPO()
						.compareToIgnoreCase(npo.trim()) == 0) {
					return auction_list.get(i);
				}
			}
		}
		return null;
	}

	private Date convertDate(String the_date) {
		SimpleDateFormat format =
				new SimpleDateFormat("MMMMM dd, yyyy");
		Date d = null;

		try {
			d = format.parse(the_date);
		} catch (ParseException e) {
			System.out.println("Bad date format");
		}

		return d;
	}
}
